package kizzo.game.tile_objects 
{
	import away3d.entities.Mesh;
	import away3d.events.Object3DEvent;
	import away3d.lights.LightBase;
	import away3d.materials.TextureMaterial;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.geom.Vector3D;	
	import kizzo.game.*;
	import kizzo.geometry.TileCoord3D;	
	import kizzo.utils.Command;
	import kizzo.utils.CommandQueue;
	import org.flashdevelop.utils.FlashConnect;

	
	public class GameCube extends TileObject
	{		
		public var links:Vector.<Link>;
		public var link_type:uint;
		
		public var incoming_link:Link;
		
		public var roll_target:TileCoord3D;
		public var tile_vector:TileCoord3D;
		
		public var boost:Boolean
		public var boost_complete:Boolean;
		
		public var repulsor:Boolean;
		
		private var goal:uint;
		
		protected var rolling:Boolean = false;				
		protected var roll_vector:Vector3D;		
		protected var parallax_vector:Point;
		protected var half_diag:Number;
		protected var roll_step:int;
		protected var roll_start_origin:Vector3D;
		protected var roll_sign_x:Number;
		protected var roll_sign_z:Number;
		
		protected var ROLL_STEP_NUMBER:int = 6;
		
		protected var fall_step:uint;
		protected var fall_speed:Number;
		protected var FALL_STEP_NUMBER:uint = 14;		
		
		public static var ROLL_COMPLETE:String = "ROLL_COMPLETE";
		public static var FALL_COMPLETE:String = "FALL_COMPLETE";		
		
		public function GameCube(mesh:Mesh, tile_coord:TileCoord3D, type:uint, light:LightBase = null) 
		{
			super(mesh, tile_coord, type, light);
			
			this.links = new Vector.<Link>();
			if (this.type == TileState.SLAVE_CUBE_A)
				this.link_type = TileState.SLAVE_LINK_A;
				
			this.boost_complete = true;
			this.repulsor = false;
		}		
		
		
		public function add_link(link_cube:GameCube):void
		{
			var link:Link = new Link(link_cube, this);
			link_cube.incoming_link = link;
			this.links.push(link);
		}
		
		
		public function remove_link(link:Link):void
		{
			for (var i:int = 0; i < this.links.length; i++)
			{
				if (links[i] == link)
					links.splice(i, 1);
			}
		}
		
				
		public function is_linked(to_cube:GameCube):Boolean
		{
			var linked:Boolean = false;
			
			for (var i:int = 0; i < this.links.length; i++)
				if (this.links[i].link_child == to_cube)
				{
					linked = true;
					break;
				}
			
			return linked;
		}
		
		
		public function add_modifier(mod:LinkModifier):void
		{
			for (var i:uint = 0; i < this.links.length; i++)
				links[i].add_modifier(mod);
		
		}
		
		
		public function apply_links(v:TileCoord3D):void
		{
			for (var i:uint = 0; i < this.links.length; i++)
			{
				var link:Link = links[i];
				//link.apply(v);
			}
		}
		
		
		public function roll(v:TileCoord3D):void
		{					
			if (this.rolling == false)
			{				
				this.rolling = true;
				this.roll_target = this.tile_coord.add(v);
				this.roll_vector = new Vector3D(v.x_m, v.y_m, v.z_m);
				this.tile_vector = v;
				this.parallax_vector = v.to_2D();
				this.half_diag = Game.TILE * Math.SQRT2 / 2;				
				this.roll_step = 0;
				
				this.roll_start_origin = new Vector3D(this.mesh.x, this.mesh.y, this.mesh.z);
				
				v.x > 0 ? this.roll_sign_x = -1 : this.roll_sign_x = 1;
				v.z > 0 ? this.roll_sign_z = 1 : this.roll_sign_z = -1;				
				
				this.addEventListener(Event.ENTER_FRAME, roll_hnd);
			}			
		}
		
		
		private function roll_hnd(e:Event):void
		{			
			var rel_pos:Number;
			var pivot_distance:Number;
			var pivot_arm_y:Number;
			
			if (this.type == TileState.MASTER_CUBE)
			{
				StarlingSprite.get_instance().parallax_move(parallax_vector, .35);
				Main.get_instance().view_3D.camera.x += roll_vector.x / 90;
				Main.get_instance().view_3D.camera.z += roll_vector.z / 90;
			}
			
			if (roll_step > ROLL_STEP_NUMBER)
			{				
				this.removeEventListener(Event.ENTER_FRAME, roll_hnd);
				this.rolling = false;
				mesh.rotationZ = 0;
				SoundLib.get_random_hit().play();
				dispatchEvent(new Event(ROLL_COMPLETE));
			}
			else
			{					
				rel_pos = (roll_step * roll_step) / (ROLL_STEP_NUMBER * ROLL_STEP_NUMBER);				
				pivot_distance = Game.TILE * (0.5 - rel_pos);
				pivot_arm_y = Math.sqrt(half_diag*half_diag - pivot_distance*pivot_distance);
				
				mesh.x = this.roll_start_origin.x + this.roll_vector.x * rel_pos;
				mesh.y = pivot_arm_y + Game.TILE_HALF_HEIGHT;
				mesh.z = this.roll_start_origin.z + this.roll_vector.z * rel_pos;
				
				roll_vector.x != 0 ? mesh.rotationZ =  roll_sign_x * rel_pos * 90 : null;
				roll_vector.z != 0 ? mesh.rotationX =  roll_sign_z * rel_pos * 90 : null;
				
				this.roll_step ++;
			}
		}	
		
		
		public function fall():void
		{
			this.fall_step = 0;
			this.fall_speed = 0;
			this.addEventListener(Event.ENTER_FRAME, fall_hnd);	
		}		
		
		
		public function set_goal(goal:uint):void
		{
			this.goal = goal;
		}
		
		public function get_goal():uint
		{
			return this.goal;
		}		
		
		
		private function fall_hnd(e:Event):void
		{		
			var rel_pos:Number;
			
			if (fall_step > FALL_STEP_NUMBER)
			{				
				this.removeEventListener(Event.ENTER_FRAME, fall_hnd);								
				dispatchEvent(new Event(FALL_COMPLETE));
			}
			else
			{	
				rel_pos = fall_step / FALL_STEP_NUMBER;			
				
				fall_speed = 4 + fall_step * 8;
				
				mesh.y -= fall_speed;				
				
				this.fall_step ++;
			}				
		}
		
		
		public function teleport(t:TileCoord3D):void
		{
			SoundLib.TELEPORT.play();
			var cq:CommandQueue = new CommandQueue();
			cq.add(new Command(tween_alpha, [0], Command.ASYNC, this, this, new Event(TWEEN_ALPHA_COMPLETE)));
			cq.add(new Command(move_to, [t], Command.SYNC, this, this));
			cq.add(new Command(tween_alpha, [1], Command.ASYNC, this, this, new Event(TWEEN_ALPHA_COMPLETE)));			
			cq.execute();	
			cq.addEventListener(CommandQueue.COMPLETE, cq_complete_hnd);
			//tween_alpha(0);
		}
		
		
		private function cq_complete_hnd(e:Event):void
		{
			trace("CQ COMPLETE");
		}
		
		
		
	}

}